package model

import (
	"database/sql"
	"fmt"
	"log"
	"time"
)

// StockData 股票数据模型
type StockData struct {
	ID                 int       `json:"id"`
	Symbol             string    `json:"symbol"`               // 股票代码
	StockName          string    `json:"stock_name"`           // 股票名称
	Current            float64   `json:"current"`              // 当前价格
	Percent            float64   `json:"percent"`              // 涨跌幅百分比
	Chg                float64   `json:"chg"`                  // 涨跌额
	Timestamp          int64     `json:"timestamp"`            // 时间戳
	Volume             float64   `json:"volume"`               // 成交量
	Amount             float64   `json:"amount"`               // 成交额
	MarketCapital      float64   `json:"market_capital"`       // 市值
	FloatMarketCapital float64   `json:"float_market_capital"` // 流通市值
	TurnoverRate       float64   `json:"turnover_rate"`        // 换手率
	Amplitude          float64   `json:"amplitude"`            // 振幅
	Open               float64   `json:"open"`                 // 开盘价
	LastClose          float64   `json:"last_close"`           // 昨日收盘价
	High               float64   `json:"high"`                 // 最高价
	Low                float64   `json:"low"`                  // 最低价
	AvgPrice           float64   `json:"avg_price"`            // 平均价格
	CurrentYearPercent float64   `json:"current_year_percent"` // 今年涨跌幅百分比
	Date               string    `json:"date"`                 // 日期字段
	Market             string    `json:"market"`               // 股票市场所属
	CreatedAt          time.Time `json:"created_at"`           // 创建时间
	UpdatedAt          time.Time `json:"updated_at"`           // 更新时间
}

// SaveStockData 将股票数据保存到数据库，根据唯一索引更新或插入数据
func SaveStockData(stockData StockData) error {
	// 获取当前日期
	stockData.Date = time.Now().Format("2006-01-02") // 格式化为 "年-月-日"

	// 查询数据库中是否已存在相同 symbol 和 date 的记录
	var count int
	err := db.QueryRow("SELECT COUNT(*) FROM stocks WHERE symbol = ? AND date = ?", stockData.Symbol, stockData.Date).Scan(&count)
	if err != nil {
		return fmt.Errorf("failed to query database: %v", err)
	}

	// 准备更新或插入语句
	var stmt *sql.Stmt
	if count > 0 {
		log.Println("数据已存在")

		// 已存在记录，执行更新操作
		stmt, err = db.Prepare("UPDATE stocks SET stock_name=?, current=?, percent=?, chg=?, timestamp=?, volume=?, amount=?, market_capital=?,float_market_capital=?, turnover_rate=?, amplitude=?, open=?, last_close=?, high=?, low=?, avg_price=?, current_year_percent=?, market=?, updated_at=NOW() WHERE symbol=? AND date=?")
		if err != nil {
			return fmt.Errorf("failed to prepare update statement: %v", err)
		}
		defer stmt.Close()
		// 执行更新或插入操作
		_, err = stmt.Exec(
			stockData.StockName,
			stockData.Current,
			stockData.Percent,
			stockData.Chg,
			stockData.Timestamp,
			stockData.Volume,
			stockData.Amount,
			stockData.MarketCapital,
			stockData.FloatMarketCapital,
			stockData.TurnoverRate,
			stockData.Amplitude,
			stockData.Open,
			stockData.LastClose,
			stockData.High,
			stockData.Low,
			stockData.AvgPrice,
			stockData.CurrentYearPercent,
			stockData.Market,
			stockData.Symbol,
			stockData.Date,
		)

	} else {
		// 不存在记录，执行插入操作
		stmt, err = db.Prepare("INSERT INTO stocks (symbol, stock_name, current, percent, chg, timestamp, volume, amount, market_capital, float_market_capital, turnover_rate, amplitude, open, last_close, high, low, avg_price, current_year_percent, date, market, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW())")
		if err != nil {
			return fmt.Errorf("failed to prepare insert statement: %v", err)
		}
		defer stmt.Close()
		// 执行更新或插入操作
		_, err = stmt.Exec(
			stockData.StockName,
			stockData.Current,
			stockData.Percent,
			stockData.Chg,
			stockData.Timestamp,
			stockData.Volume,
			stockData.Amount,
			stockData.MarketCapital,
			stockData.FloatMarketCapital,
			stockData.TurnoverRate,
			stockData.Amplitude,
			stockData.Open,
			stockData.LastClose,
			stockData.High,
			stockData.Low,
			stockData.AvgPrice,
			stockData.CurrentYearPercent,
			stockData.Date,
			stockData.Market,
		)
	}

	if err != nil {
		return fmt.Errorf("failed to execute query: %v", err)
	}

	log.Println("Stock data saved to database successfully")

	return nil
}
